package com.dify.knowledge.controller;

import com.dify.knowledge.service.SopService;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * SOP生成控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/sop")
@Validated
public class SopController {

    private final SopService sopService;

    public SopController(SopService sopService) {
        this.sopService = sopService;
    }

    /**
     * 生成SOP
     * 
     * @param request 生成请求
     * @return SOP文件或内容
     */
    @PostMapping("/generate")
    public ResponseEntity<?> generateSop(@RequestBody @Validated SopGenerateRequest request) {
        log.info("收到SOP生成请求，主题：{}，格式：{}", request.getTopic(), request.getFormat());
        
        try {
            // 生成SOP内容
            String content = sopService.generateSopContent(request.getTopic());
            
            // 如果没有相关知识
            if (content == null) {
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("success", false);
                errorResponse.put("message", "无相关知识");
                errorResponse.put("detail", "知识库中没有关于主题'" + request.getTopic() + "'的相关内容，无法生成SOP");
                return ResponseEntity.ok(errorResponse);
            }
            
            // 根据格式返回不同类型的响应
            String format = request.getFormat() != null ? request.getFormat().toLowerCase() : "markdown";
            
            if ("pdf".equals(format)) {
                // 转换为PDF并返回文件下载
                byte[] pdfBytes = sopService.convertToPdf(content);
                
                String fileName = generateFileName(request.getTopic(), "pdf");
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_PDF);
                headers.set("Content-Disposition", buildContentDisposition("attachment", fileName));
                headers.setContentLength(pdfBytes.length);
                
                log.info("SOP生成成功，格式：PDF，文件名：{}", fileName);
                return ResponseEntity.ok()
                        .headers(headers)
                        .body(pdfBytes);
                
            } else {
                // 返回Markdown格式的JSON响应
                String markdown = sopService.convertToMarkdown(content);
                
                Map<String, Object> response = new HashMap<>();
                response.put("success", true);
                response.put("hasKnowledge", true);
                response.put("content", markdown);
                response.put("topic", request.getTopic());
                response.put("format", "markdown");
                
                log.info("SOP生成成功，格式：Markdown");
                return ResponseEntity.ok(response);
            }
            
        } catch (Exception e) {
            log.error("SOP生成失败", e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("message", "SOP生成失败");
            errorResponse.put("detail", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }

    /**
     * 生成文件名
     * 
     * @param topic 主题
     * @param extension 文件扩展名
     * @return 文件名
     */
    private String generateFileName(String topic, String extension) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String sanitizedTopic = topic.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "_");
        return "SOP_" + sanitizedTopic + "_" + timestamp + "." + extension;
    }
    
    /**
     * 构建Content-Disposition头，支持中文文件名
     * 
     * @param type 类型（如attachment）
     * @param filename 文件名
     * @return Content-Disposition头值
     */
    private String buildContentDisposition(String type, String filename) {
        try {
            // 对文件名进行URL编码以支持中文
            String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8)
                    .replace("+", "%20"); // 空格用%20而不是+
            
            // 使用RFC 5987格式支持UTF-8文件名
            return type + "; filename*=UTF-8''" + encodedFilename;
        } catch (Exception e) {
            log.warn("文件名编码失败，使用ASCII文件名", e);
            // 如果编码失败，使用ASCII安全的文件名
            String asciiFilename = filename.replaceAll("[^a-zA-Z0-9._-]", "_");
            return type + "; filename=\"" + asciiFilename + "\"";
        }
    }

    /**
     * 下载SOP文件
     * 
     * @param request 下载请求
     * @return SOP文件
     */
    @PostMapping("/download")
    public ResponseEntity<?> downloadSop(@RequestBody @Validated SopDownloadRequest request) {
        log.info("收到SOP下载请求，主题：{}，格式：{}", request.getTopic(), request.getFormat());
        
        try {
            // 生成SOP内容
            String content = sopService.generateSopContent(request.getTopic());
            
            // 如果没有相关知识
            if (content == null) {
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("success", false);
                errorResponse.put("message", "无相关知识");
                errorResponse.put("detail", "知识库中没有关于主题'" + request.getTopic() + "'的相关内容，无法生成SOP");
                return ResponseEntity.ok(errorResponse);
            }
            
            // 根据格式返回文件下载
            String format = request.getFormat() != null ? request.getFormat().toLowerCase() : "markdown";
            
            if ("pdf".equals(format)) {
                // 转换为PDF并返回文件下载
                byte[] pdfBytes = sopService.convertToPdf(content);
                
                String fileName = generateFileName(request.getTopic(), "pdf");
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_PDF);
                headers.set("Content-Disposition", buildContentDisposition("attachment", fileName));
                headers.setContentLength(pdfBytes.length);
                
                log.info("SOP下载成功，格式：PDF，文件名：{}", fileName);
                return ResponseEntity.ok()
                        .headers(headers)
                        .body(pdfBytes);
                
            } else {
                // 返回Markdown文件下载
                String markdown = sopService.convertToMarkdown(content);
                
                String fileName = generateFileName(request.getTopic(), "md");
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(new MediaType("text", "markdown", StandardCharsets.UTF_8));
                headers.set("Content-Disposition", buildContentDisposition("attachment", fileName));
                
                log.info("SOP下载成功，格式：Markdown，文件名：{}", fileName);
                return ResponseEntity.ok()
                        .headers(headers)
                        .body(markdown);
            }
            
        } catch (Exception e) {
            log.error("SOP下载失败", e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("message", "SOP下载失败");
            errorResponse.put("detail", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }

    /**
     * SOP生成请求
     */
    @Data
    public static class SopGenerateRequest {
        
        @NotBlank(message = "主题不能为空")
        private String topic;
        
        private String format; // pdf 或 markdown，默认为markdown
    }
    
    /**
     * SOP下载请求
     */
    @Data
    public static class SopDownloadRequest {
        
        @NotBlank(message = "主题不能为空")
        private String topic;
        
        private String format; // pdf 或 markdown，默认为markdown
    }
}
